using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;

namespace GDI
{
    public class SectorsPrinter : PrintableItem, IEnumerable<Sector>
    {
        private readonly Sector[] f_Sectors;

        private Pen f_BorderPen;// = new Pen(Color.Red, 1.5f);
        private Brush f_FeelBrush = new SolidBrush(Color.FromArgb((int)(255 * 0.6), 0x00, 0x00, 0xff));
        private Brush f_FeelBrushOn = new SolidBrush(Color.FromArgb((int)(255 * 0.8), 0xff, 0x00, 0x00));
        private float f_r = 3;
        private float f_R = 10;
        private PointF f_Center;

        public override SmoothingMode Smoothing { get { return base.Smoothing; } set { base.Smoothing = value; f_Sectors.Foreach(s => s.Smoothing = value); } }

        public Pen BorderPen { get { return f_BorderPen; } set { f_BorderPen = value; f_Sectors.Foreach(s => s.Pen = value); } }
        public Brush FeelBrush { get { return f_FeelBrush; } set { f_FeelBrush = value; f_Sectors.Foreach(s => s.Brush = value); } }

        public float r { get { return f_r; } set { f_r = value; f_Sectors.Foreach(s => s.R_Inner = value); } }
        public float R { get { return f_R; } set { f_R = value; f_Sectors.Foreach(s => s.R_Outer = value); } }
        public PointF Center { get { return f_Center; } set { f_Center = value; f_Sectors.Foreach(s => s.Center = value); } }

        public int Count { get { return f_Sectors.Length; } }
        public Sector this[int i] { get { return f_Sectors[i]; } }

        public SectorsPrinter(int SectorsCount = 12)
        {
            f_Sectors = new Sector[SectorsCount];
            var dA = 360f / SectorsCount - 1;
            for(var i = 0; i < SectorsCount; i++)
            {
                Sector s;
                f_Sectors[i] = s = new Sector();
                s.Center = Center;
                s.Pen = f_BorderPen;
                s.Brush = f_FeelBrush;
                s.R_Inner = r;
                s.R_Outer = R;
                s.Angle = dA;
                s.StartAngle = (dA + 1) * i - 90;
                //s.Pen = null;
                Resize += (o, e) => s.Set(Center, R);
            }
            Smoothing = SmoothingMode.AntiAlias;
        }

        public override void SetEventsTo(Control c)
        {
            base.SetEventsTo(c);
            f_Sectors.Foreach(s => c.Paint += s);
            c.MouseMove += OnMouseMove;
        }

        public override void ResetEventsTo(Control c)
        {
            base.ResetEventsTo(c);
            f_Sectors.Foreach(s => c.Paint -= s);
            c.MouseMove -= OnMouseMove;
        }

        private void OnMouseMove(object Sender, MouseEventArgs E)
        {
            var p = E.Location;
            var New = f_Sectors
                .Select(s => new { S = s, R = s.Region })
                .Where(s => s.R.IsVisible(p) && s.S.Brush == f_FeelBrush);
            var Old = f_Sectors
                .Select(s => new { S = s, R = s.Region })
                .Where(s => !s.R.IsVisible(p) && s.S.Brush == f_FeelBrushOn);
            New = New.ForeachLeazy(s => s.S.Brush = f_FeelBrushOn);
            Old = Old.ForeachLeazy(s => s.S.Brush = f_FeelBrush);
            var UpdateRegion =
                New.Concat(Old)
                    .Aggregate(new Region(), (R, s) => { R.Union(s.R); return R; });
            ((Control)Sender).Invalidate();
        }

        public void Set(PointF Center, float R)
        {
            this.Center = Center;
            this.R = R;
        }

        public void Set(PointF Center, float R, float r)
        {
            this.Center = Center;
            this.R = R;
            this.r = r;
        }

        protected override void Draw(Graphics g) { }

        public IEnumerator<Sector> GetEnumerator() { return f_Sectors.Cast<Sector>().GetEnumerator(); }

        IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
    }
}